home *** CD-ROM | disk | FTP | other *** search
- #ifdef __cplusplus
- extern "C" {
- #endif
-
- #include <ctype.h>
- #include <fcntl.h>
- #include <mach/machine.h>
- #include <mach-o/dyld.h>
- #include <mach-o/fat.h>
- #include <mach-o/loader.h>
- #include <mach-o/nlist.h>
- #include <mach-o/stab.h>
- #include <stdio.h>
- #include <sys/mman.h>
- #include <sys/stat.h>
- #include <unistd.h>
-
- #ifdef __cplusplus
- }
- #endif
-
- #include "MachOUtils.h"
-
-
-
- #ifdef __cplusplus
- extern "C" {
- #endif
-
- struct mach_header *OpenImageFile(char *path,int *fd,struct stat *finfo,void **base);
- void CloseImageFile(int *fd,struct stat *finfo,void **base);
- UInt32 *FindSymbolAddressFromImage(struct mach_header *image,char *symbol);
- void *FindSectionAddressFromImage(struct mach_header *image,char *segment,char *section);
-
- #ifdef __cplusplus
- }
- #endif
-
-
-
- void *FindSymbolAddress(char *path,char *symbol)
- {
- int fd;
- struct stat finfo;
- void *base,*addr = NULL;
- struct mach_header *image;
-
- image = OpenImageFile(path,&fd,&finfo,&base);
- if (image != NULL)
- {
- addr = FindSymbolAddressFromImage(image,symbol);
- CloseImageFile(&fd,&finfo,&base);
- }
-
- return addr;
- }
-
-
-
- void *FindSectionAddress(char *path,char *segment,char *section)
- {
- int fd;
- struct stat finfo;
- void *base,*addr = NULL;
- struct mach_header *image;
-
- image = OpenImageFile(path,&fd,&finfo,&base);
- if (image != NULL)
- {
- addr = FindSectionAddressFromImage(image,segment,section);
- CloseImageFile(&fd,&finfo,&base);
- }
-
- return addr;
- }
-
-
- #if 0
- #pragma mark -
- #endif
-
-
- struct mach_header *OpenImageFile(char *path,int *fd,struct stat *finfo,void **base)
- {
- struct fat_header *fathead;
- struct fat_arch *fatarch;
- UInt32 index;
-
- *fd = 0;
- *base = NULL;
-
- *fd = open(path,0,O_RDONLY);
- if (*fd > 0)
- {
- fstat(*fd,finfo);
- *base = mmap(0,finfo->st_size,PROT_READ,MAP_FILE,*fd,0);
- if (*base != (void*)-1)
- {
- fathead = (struct fat_header*)*base;
- if (fathead->magic == FAT_MAGIC)
- {
- fatarch = (struct fat_arch*)(((char*)*base) + sizeof(struct fat_header));
- for (index = 0;index < fathead->nfat_arch;index += 1)
- if (fatarch[index].cputype == CPU_TYPE_POWERPC)
- return (struct mach_header*)(((char*)*base) + fatarch[index].offset);
- }
- else
- return (struct mach_header*)*base;
- }
- }
-
- CloseImageFile(fd,finfo,base);
- return NULL;
- }
-
-
-
- void CloseImageFile(int *fd,struct stat *finfo,void **base)
- {
- if (*fd > 0)
- {
- if (*base != NULL)
- {
- munmap(*base,finfo->st_size);
- *base = NULL;
- }
-
- close(*fd);
- *fd = 0;
- }
- }
-
-
-
- UInt32 *FindSymbolAddressFromImage(struct mach_header *image,char *symbol)
- {
- struct dysymtab_command *dysymtab;
- struct symtab_command *symtab;
- struct segment_command *segCmd;
- struct load_command *loadCmd;
- struct section *sect;
- struct nlist *sym,*symbase = NULL;
- char *str,*strings = NULL;
- UInt32 *indirectsyms,inbase = 0xFFFFFFFF;
- UInt32 lcdex,symdex,sectdex;
- UInt8 *inaddr = NULL;
-
- loadCmd = (struct load_command*)((char*)image + sizeof(struct mach_header));
- for (lcdex = 0;lcdex < image->ncmds;lcdex += 1,loadCmd = (struct load_command*)((char*)loadCmd + loadCmd->cmdsize))
- {
- if (loadCmd->cmd == LC_SEGMENT)
- {
- segCmd = (struct segment_command*)loadCmd;
- if (!strcmp("__DATA",segCmd->segname))
- {
- sect = (struct section*)((char*)segCmd + sizeof(struct segment_command));
- for (sectdex = 0;sectdex < segCmd->nsects;sectdex += 1,sect += 1)
- {
- if (!strcmp("__la_symbol_ptr",sect->sectname))
- {
- inaddr = (UInt8*)sect->addr;
- inbase = sect->reserved1;
- break;
- }
- }
- }
- }
- }
-
- if ((inaddr == NULL) || (inbase == 0xFFFFFFFF))
- return NULL;
-
- loadCmd = (struct load_command*)((char*)image + sizeof(struct mach_header));
- for (lcdex = 0;lcdex < image->ncmds;lcdex += 1,loadCmd = (struct load_command*)((char*)loadCmd + loadCmd->cmdsize))
- {
- if (loadCmd->cmd == LC_SYMTAB)
- {
- symtab = (struct symtab_command*)loadCmd;
- symbase = (struct nlist*)((char*)image + symtab->symoff);
- strings = (char*)image + symtab->stroff;
- break;
- }
- }
-
- if ((symbase == NULL) || (strings == NULL))
- return NULL;
-
- loadCmd = (struct load_command*)((char*)image + sizeof(struct mach_header));
- for (lcdex = 0;lcdex < image->ncmds;lcdex += 1,loadCmd = (struct load_command*)((char*)loadCmd + loadCmd->cmdsize))
- {
- if (loadCmd->cmd == LC_DYSYMTAB)
- {
- dysymtab = (struct dysymtab_command*)loadCmd;
- indirectsyms = (UInt32*)((char*)image + dysymtab->indirectsymoff);
-
- for (symdex = inbase;symdex < dysymtab->nindirectsyms;symdex += 1)
- {
- sym = &symbase[indirectsyms[symdex]];
- str = (sym->n_un.n_strx != 0) ? (strings + sym->n_un.n_strx) : (char*)"";
- if (!strcmp(symbol,str))
- {
- return (UInt32*)(inaddr + ((symdex - inbase) * 4));
- }
- }
-
- break;
- }
- }
-
- return NULL;
- }
-
-
-
- void *FindSectionAddressFromImage(struct mach_header *image,char *segment,char *section)
- {
- struct segment_command *segCmd;
- struct load_command *loadCmd;
- struct section *sect;
- UInt32 lcdex,sectdex;
-
- loadCmd = (struct load_command*)((char*)image + sizeof(struct mach_header));
- for (lcdex = 0;lcdex < image->ncmds;lcdex += 1,loadCmd = (struct load_command*)((char*)loadCmd + loadCmd->cmdsize))
- {
- if (loadCmd->cmd == LC_SEGMENT)
- {
- segCmd = (struct segment_command*)loadCmd;
- if (!strcmp(segment,segCmd->segname))
- {
- sect = (struct section*)((char*)segCmd + sizeof(struct segment_command));
- for (sectdex = 0;sectdex < segCmd->nsects;sectdex += 1,sect += 1)
- if (!strcmp(section,sect->sectname))
- return (void*)sect->addr;
- }
- }
- }
-
- return NULL;
- }
-